/**
 * 
 */
package com.sfeir.client.activity;

import static com.sfeir.client.util.Constants.BUTTON_HEIGHT;
import static com.sfeir.client.util.Constants.BUTTON_WIDTH;
import static com.sfeir.client.util.Constants.STAR_WIDTH;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Image;
import com.google.web.bindery.event.shared.EventBus;
import com.sfeir.canvas.activities.client.AbstractCanvasActivity;
import com.sfeir.canvas.activities.client.event.PageChangeEvent;
import com.sfeir.canvas.util.client.ResourceManager;
import com.sfeir.client.i18n.TetrisConstants;
import com.sfeir.client.i18n.TetrisMessages;
import com.sfeir.client.service.AppServiceAsync;
import com.sfeir.client.util.Constants;
import com.sfeir.shared.Level;

/**
 * @author François LAROCHE
 * 
 */
public class GameOverActivity extends AbstractCanvasActivity {

	private static final int BACK_BUTTON_X = 450;
	private static final int BACK_BUTTON_Y = 470;

	private static final int REFRESH_BUTTON_X = 550;
	private static final int REFRESH_BUTTON_Y = 470;

	private static final int TWITTER_BUTTON_X = 370;
	private static final int TWITTER_BUTTON_Y = 380;

	private static final int NEXT_BUTTON_X = 650;
	private static final int NEXT_BUTTON_Y = 470;

	private static final String GAME_URL = "sfeir-2012.appspot.com";
	private static final String TWITTER_REQUEST = "https://twitter.com/intent/tweet?original_referer=http%3A%2F%2F"
			+ GAME_URL + "%2F&related=Tetris&source=tweetbutton&url=http%3A%2F%2F" + GAME_URL + "%2F&text=";

	private final Image panel;
	private final Image redo;
	private final Image next;
	private final Image back;
	private final Image star;
	private final Image emptyStar;
	private final Image twitter;
	private final TetrisConstants texts;
	private final AppServiceAsync service;
	private final TetrisMessages messages;

	private int score;
	private EventBus bus;
	private Level level;
	private int starsNb;

	public GameOverActivity(ResourceManager manager, AppServiceAsync service) {
		this.service = service;
		this.texts = GWT.create(TetrisConstants.class);
		this.panel = manager.getImage(Constants.KEY_IMAGE_PANEL);
		this.redo = manager.getImage(Constants.KEY_IMAGE_REFRESH);
		this.next = manager.getImage(Constants.KEY_IMAGE_NEXT);
		this.back = manager.getImage(Constants.KEY_IMAGE_BACK);
		this.star = manager.getImage(Constants.KEY_IMAGE_STAR);
		this.emptyStar = manager.getImage(Constants.KEY_IMAGE_STAR_EMPTY);
		this.twitter = manager.getImage(Constants.KEY_IMAGE_TWITTER);
		this.messages = GWT.create(TetrisMessages.class);
	}


	@Override
	public void start(Canvas canvas, EventBus bus) {
		this.bus = bus;
		this.paint(this.starsNb, canvas.getContext2d());
	}


	@Override
	public void init(Map<String, Object> context) {
		this.level = (Level) context.get(Constants.LEVEL_PARAM);
		this.starsNb = (Integer) context.get("number");
		this.score = (Integer) context.get("score");
	}


	/**
	 * Method allowing to paint the component
	 * 
	 * @param starsNb
	 */
	private void paint(int starsNb, Context2d ctx) {
		// Display the score
		ctx.save();
		ctx.drawImage(ImageElement.as(this.panel.getElement()), 0, 0);
		ctx.setFont("bold 28pt calibri");
		ctx.setFillStyle("black");
		ctx.fillText(texts.score() + " " + this.level.getOrder(), 230, 200);
		ctx.setFont("25pt calibri");
		ctx.fillText("" + this.score, 385, 250);

		// Display the widget link images
		ctx.drawImage(ImageElement.as(this.back.getElement()), BACK_BUTTON_X, BACK_BUTTON_Y);
		ctx.drawImage(ImageElement.as(this.redo.getElement()), REFRESH_BUTTON_X, REFRESH_BUTTON_Y);
		ctx.drawImage(ImageElement.as(this.twitter.getElement()), TWITTER_BUTTON_X, TWITTER_BUTTON_Y, STAR_WIDTH,
				STAR_WIDTH);

		// Draw next level only if we have stars
		if (starsNb > 0) {
			ctx.drawImage(ImageElement.as(this.next.getElement()), NEXT_BUTTON_X, NEXT_BUTTON_Y);
		}
		drawStars(starsNb, ctx);
		ctx.restore();
	}
	
	@Override
	public void onClick(ClickEvent event) {
		int x = event.getX();
		int y = event.getY();

		// Click on the back button
		if (x >= BACK_BUTTON_X && x <= BACK_BUTTON_X + BUTTON_WIDTH && y >= BACK_BUTTON_Y
				&& y <= BACK_BUTTON_Y + BUTTON_HEIGHT) {

			this.bus.fireEvent(new PageChangeEvent(PageChangeEvent.BACK, null));
			return;
		}
		// Click on the refresh button
		if (x >= REFRESH_BUTTON_X && x <= REFRESH_BUTTON_X + BUTTON_WIDTH && y >= REFRESH_BUTTON_Y
				&& y <= REFRESH_BUTTON_Y + BUTTON_HEIGHT) {

			Map<String, Object> context = new HashMap<String, Object>();
			context.put(Constants.LEVEL_PARAM, this.level);
			this.bus.fireEvent(new PageChangeEvent(PageChangeEvent.NEXT, context));
			return;
		}

		// Click on the twitter link
		if (x >= TWITTER_BUTTON_X && x <= TWITTER_BUTTON_X + BUTTON_WIDTH && y >= TWITTER_BUTTON_Y
				&& y <= TWITTER_BUTTON_Y + BUTTON_HEIGHT) {
			Window.open(TWITTER_REQUEST + messages.twitterScoreMsg(score + "", level.getOrder() + ""), "",
					"toolbar=0,menubar=0,location=0,scrollbars=1,width=500,height=400,resizable=0");
		}

		// Click on the next Level Button
		if (x >= NEXT_BUTTON_X && x <= NEXT_BUTTON_X + BUTTON_WIDTH && y >= NEXT_BUTTON_Y
				&& y <= NEXT_BUTTON_Y + BUTTON_HEIGHT) {

			this.service.getLevels(new AsyncCallback<List<Level>>() {

				@Override
				public void onSuccess(List<Level> result) {
					for (Level lvl : result) {
						if (lvl.getOrder() == level.getOrder() + 1) {
							Map<String, Object> context = new HashMap<String, Object>();
							context.put(Constants.LEVEL_PARAM, lvl);
							bus.fireEvent(new PageChangeEvent(PageChangeEvent.NEXT, context));
							return;
						}
					}
				}

				@Override
				public void onFailure(Throwable caught) {

				}
			});
			return;
		}
	}

	/**
	 * Method allowing to paint the stars associated to the passed score
	 * 
	 * @param starsNb
	 */
	private void drawStars(int starsNb, Context2d ctx) {
		int margin = (Constants.CANVAS_WIDTH - 3 * STAR_WIDTH) / 2;
		for (int i = 0; i < 3; i++) {
			if (i < starsNb) {
				ctx.drawImage(ImageElement.as(this.star.getElement()), margin - 10 + i * (STAR_WIDTH + 5), 320);
			} else {
				ctx.drawImage(ImageElement.as(this.emptyStar.getElement()), margin - 10 + i * (STAR_WIDTH + 5),
						320);
			}
		}
	}

}
